﻿/////////////////////////////////////////////////////////////////////
//
//	Map_FVG C# Class Library.
//
//	Print_pdf
//
//	autore: Gustavo Mainardi 
//	versione: 1.0
//	data: 01/12/2015
//
//
//	Cronologia delle versioni:
//
//	Versione 1.0 01/12/2015
//		versione originale
//
//////////////////////////////////////////////////////////////////////////
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Diagnostics;
using System.Globalization;
using PdfFileWriter;

namespace Map_Fvg
{
    public partial class Print 
    {
        private const Double DegToRad = Math.PI / 180.0;
        private static Double PageWidth = 210.0;
        private static Double PageHeight = 297.0;
        private static Double Orig_X = 20.0;
        private static Double Orig_Y = 20.0;
        private static Double Margin_X = 20.0;
        private static Double Margin_Y = 20.0;
        private const Double HeadingHeight = 6.0;
        private static Double DispWidth = PageWidth - 2 * Orig_X;
        private static Double DispHeight = PageHeight - 2 * Orig_Y - HeadingHeight;
        private PdfDocument Document;
        private PdfFont ArialNormal;
        private PdfFont ArialBold;


        void drawPdf(string FileName, string sizeP, bool bLandscape)
        {
            double PageWidth1 = 210.0 ;
            double PageHeight1 = 297.0;

            if (sizeP.Contains("A3"))
            {
                PageWidth1 = 297.0 ;
                PageHeight1 = 420.0;
            }
            else if (sizeP.Contains("A2"))
            {
                PageWidth1 = 420.0 ;
                PageHeight1 = 594.0;
            }
            else if (sizeP.Contains("A1"))
            {
                PageWidth1 = 594.0 ;
                PageHeight1 = 840.0;
            }

            if (bLandscape)
            {
                PageWidth = PageHeight1;
                PageHeight = PageWidth1;
                DispWidth = PageHeight1 - Orig_X - Margin_X;
                DispHeight = PageWidth1 - Orig_Y - Margin_Y;
            }
            else
            {
                PageWidth = PageWidth1;
                PageHeight = PageHeight1;
                DispWidth = PageWidth1 - Orig_X - Margin_X;
                DispHeight = PageHeight1 - Orig_Y - Margin_Y;
            }
            Double ScaleFactor = 3.0;
            Document = new PdfDocument(PageWidth, PageHeight, ScaleFactor, FileName);
            Document.Debug = false;
           
            ArialNormal = new PdfFont(Document, "Arial", FontStyle.Regular, true);
            ArialBold = new PdfFont(Document, "Arial", FontStyle.Bold, true);

            // create page contents
            CreatePage1Contents();

            // create pdf file
            Document.CreateFile();
  
            // start default PDF reader and display the file
            Process Proc = new Process();
            Proc.StartInfo = new ProcessStartInfo(FileName);
            Proc.Start();

        }

        ///////////////////////////////////////////////////////////////////
        // create page1 contents
        ////////////////////////////////////////////////////////////////////

        public void CreatePage1Contents()
        {
            PdfPage Page = new PdfPage(Document);

            PdfContents Contents = new PdfContents(Page);

            CreateBaseContents(Contents);

            drawPdfMap(Contents);

            return;
        }
 
        private void CreateBaseContents(PdfContents Contents)
        {

            // save graphics state
            Contents.SaveGraphicsState();

                        // frame
            Contents.SetLineWidth(0.5);
            Contents.SetColorStroking(Color.Black);
            Contents.DrawRectangle(Orig_X, Orig_Y, DispWidth, DispHeight, PaintOp.CloseStroke);// PaintOp.CloseStroke);

            //
            //      intestazione
            string line = string.Empty;
            int sizeFont = 15;
            double leftMargin = 0;
    
            if (ViewQ.noFilesSelected == 1)
            {
                line = FormIniz.nameElement;
                line = string.Concat(line, "   ", ViewQ.IDtavol);
            }
            else
            {
                int iElem = 0;
                for (int i = 0; i < 4; ++i)
                {
                    string ss = UnioneDialog.fileUnione[i];
                    if (ss != string.Empty)
                    {
                        if (iElem > 0) line = string.Concat(line, " / ");
                        line = string.Concat(line, ss.Trim());
                        ++iElem;
                        if (iElem == ViewQ.noFilesSelected) break;
                    }
                }
            }
            line = line.Trim();

            leftMargin = 0.2 * PageWidth;
            Contents.DrawText(ArialBold, sizeFont, leftMargin, PageHeight - Orig_Y + HeadingHeight,
                         TextJustify.Left, line);
            double stringWidth = ArialBold.TextWidth((double)sizeFont, line);

            line = "scala  1:";
            line = string.Concat(line, textBox1.Text);
            leftMargin = leftMargin + stringWidth + 60;
      //      if (!bLandscape) leftMargin = 130;
            sizeFont = 12;
            Contents.DrawText(ArialBold, sizeFont, leftMargin, PageHeight - Orig_Y + HeadingHeight,
                         TextJustify.Left, line);

            line = initX.ToString();
            string s3 = (initX + width1).ToString();
            string s5 = (initY + height1).ToString();
            line = string.Concat(line, " / ", initY.ToString(), " - ", s3, " / ", s5);
            leftMargin += 50;
 //           if (!bLandscape) leftMargin = 170;
            sizeFont = 10;
            Contents.DrawText(ArialNormal, sizeFont, leftMargin, PageHeight - Orig_Y + HeadingHeight,
                         TextJustify.Left, line);

            // restore graphics state
            Contents.RestoreGraphicsState();

            return;
        }

    private void drawPdfMap(PdfContents Contents)
        {

            Contents.SaveGraphicsState();

            char[] delimiterChars0 = { ',', '/' };
            string[] words;
            NumberFormatInfo nfi = new CultureInfo("en-US", false).NumberFormat;

            double scala = 1.0 / double.Parse(this.textBox1.Text);
            double Xdiff = 1000 * (ViewQ.Xmax - ViewQ.Xmin) * scala;
            double Ydiff = 1000 * (ViewQ.Ymax - ViewQ.Ymin) * scala;

            double YYtrasl = 1000.0 * (ViewQ.vert[0].Y - ViewQ.vert[3].Y) * scala;

            double alphaR = ViewQ.alpha * Math.PI / 180.0D;
            double sinA = Math.Sin(alphaR);
            double cosA = Math.Cos(alphaR);
            double Ydiff1 = Ydiff - YYtrasl;

            double RGyy1 = height1 * Ydiff1 / DispHeight;
            double initXX = initX;
            double initYY = RGyy1 - initY - height1;
            double XX = initXX * cosA - initYY * sinA;
            double YY = initXX * sinA + initYY * cosA;
            double Xoff = Orig_X - (initXX / RGxx) * Xdiff;
            double Yoff = Orig_Y - (initYY / RGyy1) * Ydiff1;

            Contents.DrawRectangle(Orig_X, Orig_Y, DispWidth, DispHeight, PaintOp.ClipPathWnr);

            //
            //      line_shp
            //
            Scarpata scr = new Scarpata();

            for (int i = 0; i < ViewQ.nShapes; ++i)  //     ViewQ.nShapes; ++i)
            {
                int nVertices = ViewQ.vectShapes[i].nVertices;
                int ipnt = ViewQ.vectShapes[i].pntpL;
                int pntSimb = ViewQ.vectShapes[i].pntSimb;
                if (ViewQ.vectS[pntSimb].selected == 0) continue;
                int visib = ViewQ.vectS[pntSimb].visib;
                if (visib == 0) continue;

                Color icolor = ViewQ.vectS[pntSimb].icolor;
                //            Contents.SetColorNonStroking(icolor);
                Contents.SetColorStroking(icolor);

                string ss = ViewQ.vectS[pntSimb].tratto;
                int type = ViewQ.vectS[pntSimb].penType;

                double width = 0;
                double interpasso = 0;
                string s1;
                double[] dashValues = { 0, 0 };
                double diam = 0;

                switch (type)
                {
                    case 1:
                        int ipos = ss.IndexOf('/');
                        int len = ss.Length;
                        ++ipos;
                        s1 = ss.Substring(ipos, len - ipos);
                        width = double.Parse(s1, nfi);
                        break;
                    case 11:            // scarpata (ciglio)
                    case 12:            // scarpata (piede)
                    case 13:            // scarpata rivestita (ciglio)
                        ipos = ss.IndexOf('/');
                        len = ss.Length;
                        ++ipos;
                        s1 = ss.Substring(ipos, len - ipos);
                        words = s1.Split(delimiterChars0);
                        dashValues[0] = double.Parse(words[0], nfi);
                        dashValues[1] = double.Parse(words[1], nfi);
                        interpasso = double.Parse(words[2], nfi);
                        width = double.Parse(words[3], nfi);
                        break;
                    case 26:         //  limite di bosco
                        ipos = ss.IndexOf('/');
                        len = ss.Length;
                        ++ipos;
                        s1 = ss.Substring(ipos, len - ipos);
                        words = s1.Split(delimiterChars0);
                        width = double.Parse(words[4], nfi);
                        dashValues[0] = double.Parse(words[0], nfi); // / width;
                        dashValues[1] = double.Parse(words[1], nfi); // / width;
                        diam = double.Parse(words[2], nfi);
                        interpasso = double.Parse(words[3], nfi);
                        break;
                    case 33:        //  ruderi
                        ipos = ss.IndexOf('/');
                        len = ss.Length;
                        ++ipos;
                        s1 = ss.Substring(ipos, len - ipos);
                        words = s1.Split(delimiterChars0);
                        dashValues[0] = double.Parse(words[0], nfi);
                        dashValues[1] = double.Parse(words[1], nfi);
                        width = double.Parse(words[2], nfi);
                        break;
                     case 38:            //  limite di comune
                        ipos = ss.IndexOf('/');
                        len = ss.Length;
                        ++ipos;
                        s1 = ss.Substring(ipos, len - ipos);
                        words = s1.Split(delimiterChars0);
                        width = double.Parse(words[2], nfi);
                        diam = double.Parse(words[0], nfi);
                        interpasso = double.Parse(words[1], nfi);
                        break;
                    case 40:         //  curva di livello intermedia
                    case 41:         //  curva di livello direttrice
                        ipos = ss.IndexOf('/');
                        len = ss.Length;
                        ++ipos;
                        s1 = ss.Substring(ipos, len - ipos);
                        width = double.Parse(s1, nfi);
                        break;
                    case 42:     //  sentieri CAI
                        ipos = ss.IndexOf('/');
                        len = ss.Length;
                        ++ipos;
                        s1 = ss.Substring(ipos, len - ipos);
                        width = double.Parse(s1, nfi);
                        dashValues[0] = 0F;
                        break;
                    case 43:        //  sentieri
                    case 44:        //  bordo di rotabile
                    case 60:        //  tracce sentieri
                        ipos = ss.IndexOf('/');
                        len = ss.Length;
                        ++ipos;
                        s1 = ss.Substring(ipos, len - ipos);
                        words = s1.Split(delimiterChars0);
                        width = double.Parse(words[2], nfi);
                        dashValues[0] = double.Parse(words[0], nfi);
                        dashValues[1] = double.Parse(words[1], nfi);
                        break;
                    default:
                        width = 0F;
                        break;
                }
                if (width == 0) continue;

                Contents.SetLineWidth(width);
                Contents.SetDashLine(null, 0);
                if (type != 12 && dashValues[0] > 0) Contents.SetDashLine(dashValues, 0);

                PointF[] polyD = new PointF[nVertices];
                for (int j = 0; j < nVertices; ++j)
                {
                    double XX1 = 1000.0 * (ViewQ.PL[ipnt].X - ViewQ.Xmin) * scala;
                    double YY1 = 1000.0 * (ViewQ.PL[ipnt].Y - ViewQ.Ymin) * scala - YYtrasl;
                    polyD[j].X = (float)(XX1 * cosA + YY1 * sinA) + (float)Xoff;
                    polyD[j].Y = (float)(-XX1 * sinA + YY1 * cosA) + (float)Yoff;
                    ++ipnt;
                }
                if (type == 11 || type == 12 || type == 13)
                {
                    scr.scarpata(Contents, polyD, width, dashValues[0], dashValues[1], interpasso, i, type);
                }
                else if (type == 38)
                {
                    dashValues[0] = diam;
                    dashValues[1] = interpasso - diam;
                    Contents.SetDashLine(dashValues, 0);
                    //             dc.DrawCurve(iPen, polygon);
                }
                else
                {
                    if (dashValues[0] == 0) drawLines(Contents, polyD);
                    else scr.dashLine(Contents, polyD, width, dashValues, type, i);
                }

                if (type == 26 && diam > 0)        //  limite di bosco
                {
                    scr.limiteDiBosco(Contents, polyD, width, dashValues[0], dashValues[1], interpasso, diam, i);
                }
            }

            Contents.RestoreGraphicsState();


            Contents.SaveGraphicsState();

            double X0, Y0, X1, Y1;
            double Xmin = 1000.0 * ViewQ.vert[0].X;
            double Ymin = 1000.0 * ViewQ.vert[3].Y;
            double dscale = 1.0;

            Contents.SetDashLine(null, 0);
            Contents.SetLineWidth(0.2);
            Contents.SetColorNonStroking(Color.Black);
            Contents.SetColorStroking(Color.Black);

            //
            //  legenda asse orizzontale
            //
            double coordX_B = Orig_Y - 10;
            int sizeFont = 10;
            for (int i = 0; i < 20; ++i)
            {
                if (ViewQ.retic[i].X == 0) break;
                X0 = 1000.0 * (ViewQ.retic[i].X - ViewQ.Xmin) * scala;
                Y0 = initYY;
                double XX0 = (X0 * cosA + Y0 * sinA) + Xoff;
                if (XX0 < Orig_X || XX0 > Orig_X + DispWidth) continue;
                string ss = ViewQ.retic[i].X.ToString();
                int length = ss.Length;
                string line = ss.Substring(2, length - 2);
                double stringWidth = ArialBold.TextWidth((double)sizeFont, line);
                XX0 = XX0 - stringWidth / 2;
                Y0 = coordX_B; // +stringSize.Height;

                Contents.DrawText(ArialBold, sizeFont, XX0, Y0, line);
            }
            //
            //  legenda asse verticale
            //
            double coordY_S = Orig_X - 8;
            double angle = 90.0 * DegToRad;
            dscale = 1.0;
            Contents.TranslateScaleRotate(coordY_S, 0.0, dscale, angle);
            for (int i = 0; i < 20; ++i)
            {
                if (ViewQ.retic[i].Y == 0) break;
                Y0 = 1000.0 * (ViewQ.retic[i].Y - ViewQ.vert[3].Y) * scala - YYtrasl;
                X0 = (initXX / RGxx) * Xdiff;

                double XX0 = (X0 * cosA + Y0 * sinA) + Xoff;
                double YY0 = (-X0 * sinA + Y0 * cosA) + Yoff;

                if (YY0 < Orig_Y || YY0 > coordY_S + DispHeight) continue;

                X0 = coordY_S;  //(ViewQ.vert[0].X - ViewQ.Xmin) * scalaX + Xorig;
                string ss = ViewQ.retic[i].Y.ToString();
                int length = ss.Length;
                string line = ss.Substring(2, length - 2);

                double stringWidth = (float)ArialNormal.TextWidth((double)sizeFont, line);

                Contents.DrawText(ArialNormal, sizeFont, YY0, 0.0, line);
            }
            Contents.TranslateScaleRotate(0.0, 0.0, dscale, -angle);
            Contents.TranslateScaleRotate(-coordY_S, 0.0, dscale, 0.0);

            //
            //      definizione area clipping
            //
            Contents.DrawRectangle(Orig_X, Orig_Y, DispWidth, DispHeight, PaintOp.ClipPathWnr);

            //
            //     linee verticali reticolato
            //
            for (int i = 0; i < 20; ++i)
            {
                if (ViewQ.retic[i].X == 0) break;
                X0 = (1000.0 * ViewQ.retic[i].X - Xmin) * scala;
                X1 = X0;
                Y0 = (1000.0 * ViewQ.vert[3].Y - Ymin) * scala - YYtrasl;
                Y1 = (1000.0 * ViewQ.vert[1].Y - Ymin) * scala - YYtrasl;

                double XX0 = (X0 * cosA + Y0 * sinA) + Xoff;
                if (XX0 < Orig_X || XX0 > Orig_X + DispWidth) continue;
                double YY0 = (-X0 * sinA + Y0 * cosA) + Yoff;
                double XX1 = (X1 * cosA + Y1 * sinA) + Xoff;
                double YY1 = (-X1 * sinA + Y1 * cosA) + Yoff;

                Contents.DrawLine(XX0, YY0, XX1, YY1);
            }
            //
            //     linee orizzontali reticolato
            //
            for (int i = 0; i < 20; ++i)
            {
                if (ViewQ.retic[i].Y == 0) break;
                Y0 = 1000.0 * (ViewQ.retic[i].Y - ViewQ.vert[3].Y) * scala - YYtrasl;
                Y1 = Y0;

                X0 = (initXX / RGxx) * Xdiff;
                X1 = X0 + DispWidth + Orig_X;
                double XX0 = (X0 * cosA + Y0 * sinA) + Xoff;
                double YY0 = (-X0 * sinA + Y0 * cosA) + Yoff;
                if (YY0 < Orig_Y || YY0 > Orig_Y + DispHeight) continue;

                double XX1 = (X1 * cosA + Y1 * sinA) + Xoff;
                double YY1 = (-X1 * sinA + Y1 * cosA) + Yoff;

                Contents.DrawLine(XX0, YY0, XX1, YY1);
            }

            Contents.RestoreGraphicsState();

            //
            //      text_shp
            //

            Contents.SaveGraphicsState();
            Contents.DrawRectangle(Orig_X, Orig_Y, DispWidth, DispHeight, PaintOp.ClipPathWnr);
            for (int i = 0; i < ViewQ.nShapesT; ++i)  //    nShapesT; ++i)
            {

                if (ViewQ.vectShapesT[i].selected == 0) continue;
                if (ViewQ.vectShapesT[i].modifica == 2) continue;
                int pntSimb = ViewQ.vectShapesT[i].pntSimb;
                if (ViewQ.vectT[pntSimb].selected == 0) continue;
                int visib = ViewQ.vectT[pntSimb].visib;
                if (visib == 0) continue;

                Color icolor = ViewQ.vectT[pntSimb].icolor;
                Contents.SetColorStroking(icolor);

                Font iFont = ViewQ.vectT[pntSimb].iFont;            //  ???????????????
                angle = ViewQ.vectShapesT[i].GMrotation;
                double angleR = 0.0;
                bool bAngle = false;
                if (angle != 0.0F)
                {
                    bAngle = true;
                    angleR = angle * Math.PI / 180.0D;
                }
                //          Pen iPen = new Pen(icolor, width);

                //               Point Pnt = new Point();
                string stx = ViewQ.vectShapesT[i].testo.Trim();

                double XX1 = 1000.0 * (ViewQ.vectShapesT[i].XX.X - ViewQ.Xmin) * scala;
                double YY1 = 1000.0 * (ViewQ.vectShapesT[i].XX.Y - ViewQ.Ymin) * scala - YYtrasl;
                double PntX = XX1 * cosA + YY1 * sinA + Xoff;
                double PntY = -XX1 * sinA + YY1 * cosA + Yoff;

                char[] charArr = stx.ToCharArray();
                int icar = 0;
                bool flag = true;
                foreach (char ch in charArr)
                {
                    if (flag && ch == ' ')
                    {
                        ++icar;
                        flag = false;
                    }
                    if (ch != ' ') flag = true;
                }

                string space = " ";
                sizeFont = (int)iFont.Size;
                float fspace = (float)ArialNormal.TextWidth(sizeFont, space);

                int ipt = 0;
                int ncar = 0;
                int len = charArr.Length;
                for (int ii = 0; ii < icar + 1; ++ii)
                {
                    string sty = string.Empty;

                    if (icar == 0)
                    {
                        string stz = new string(charArr);
                        sty = stz;
                    }

                    if (icar > 0)
                    {
                        int j;
                        for (j = ipt; j < len; ++j) if (charArr[j] == ' ') break;
                        int len1 = j - ipt;
                        ncar = 1;
                        char[] charArr2 = new char[len1];
                        for (int k = 0; k < len1; ++k) charArr2[k] = charArr[k + ipt];
                        ipt = j + 1;
                        string stz = new string(charArr2);
                        sty = stz;

                        while (ipt < len)
                        {
                            if (charArr[ipt] != ' ') break;
                            ++ipt;
                            ++ncar;
                        }
                    }

                    double width2 = ArialNormal.TextWidth(sizeFont, sty);
                    PdfRectangle box = ArialNormal.TextBoundingBox(sizeFont, sty);
                    double height2 = box.Top - box.Bottom;

                    if (bAngle)
                    {
                        Contents.Translate(PntX, PntY);
                        Contents.TranslateScaleRotate(0.0, 0.0, 1.0, angleR);
                        //               Contents.DrawOval(pntR.X, pntR.Y, pntR.Width, pntR.Height, PaintOp.CloseStroke);
                        Contents.SetColorNonStroking(Color.White);
                        Contents.SetColorStroking(Color.White);
                        Contents.DrawRectangle(0.0, 0.0, width2, height2, PaintOp.Fill);

                        Contents.SetColorNonStroking(icolor);
                        Contents.DrawText(ArialNormal, sizeFont, 0.0, 0.0, TextJustify.Left, sty);
                        Contents.TranslateScaleRotate(0.0, 0.0, 1.0, -angleR);
                        Contents.Translate(-PntX, -PntY);
                        if (icar > 0)
                        {
                            PntX += (width2 + ncar * fspace) * Math.Cos(angleR);
                            PntY += (width2 + ncar * fspace) * Math.Sin(angleR);
                        }
                    }
                    else
                    {
                        Contents.SetColorNonStroking(Color.White);
                        Contents.SetColorStroking(Color.White);
                        Contents.DrawRectangle(PntX, PntY, width2, height2, PaintOp.Fill);

                        Contents.SetColorNonStroking(icolor);
                        Contents.DrawText(ArialNormal, sizeFont, PntX, PntY, TextJustify.Left, sty);
                        if (icar > 0)
                        {
                            PntX += width2 + ncar * fspace;
                        }

                    }
                }
                continue;
            }
            Contents.RestoreGraphicsState();

            //
            //      point_shp
            //
    
                double rapp = 1.0;
                if (scala != 0.0002)
                {
                    rapp = 5000.0 * scala;
                }
                Contents.SaveGraphicsState();
                Contents.DrawRectangle(Orig_X, Orig_Y, DispWidth, DispHeight, PaintOp.ClipPathWnr);

                for (int i = 0; i < ViewQ.nShapesP; ++i)        //  ViewQ.nShapesP; ++i)
                {

                    int pntSimb = ViewQ.vectShapesP[i].pntSimb;
                    if (ViewQ.vectP[pntSimb].selected == 0) continue;
                    int visib = ViewQ.vectP[pntSimb].visib;
                    if (visib == 0) continue;
                    string codex = ViewQ.vectP[pntSimb].codice;

                    int codice = ViewQ.vectP[pntSimb].simbolo;
                    if (codice == 0) continue;

                    Color icolor = ViewQ.vectP[pntSimb].icolor;
                    Contents.SetColorStroking(icolor);
                    Font iFont = ViewQ.vectP[pntSimb].iFont;
                    angle = -ViewQ.vectShapesP[i].GMrotation;
                    double angleR = 0.0;
                    bool bAngle = false;
                    if (angle != 0.0)
                    {
                        bAngle = true;
                        angleR = -angle * Math.PI / 180.0D;
                    }

                    double XX1 = 1000.0 * (ViewQ.vectShapesP[i].XX.X - ViewQ.Xmin) * scala;
                    double YY1 = 1000.0 * (ViewQ.vectShapesP[i].XX.Y - ViewQ.Ymin) * scala - YYtrasl;
                    double PntX = XX1 * cosA + YY1 * sinA + Xoff;
                    double PntY = -XX1 * sinA + YY1 * cosA + Yoff;

                    sizeFont = (int)iFont.Size;
                    if (codice != 1)
                    {
                        double width = 0;
                        double height = 0;

                        string fileName = ViewQ.vectP[pntSimb].fileName.Trim();
                        if (!string.IsNullOrEmpty(fileName))
                        {
                            string fileX = FormIniz.bitmapFolder;
                            fileX = string.Concat(fileX, fileName);
                            string ss = ViewQ.vectP[pntSimb].paramSimb;
                            switch (codice)
                            {
                                case 5:         //  sorgente perenne
                                case 14:        //  croce isolata
                                case 22:        //  pino, altra conifera
                                case 38:        //  pino mugo
                                    int ipos = ss.IndexOf('/');
                                    ++ipos;
                                    int len = ss.Length;
                                    string s1 = ss.Substring(ipos, len - ipos);
                                    words = s1.Split(delimiterChars0);
                                    width = double.Parse(words[0], nfi);
                                    height = double.Parse(words[1], nfi);
                                    break;
                            }
                            PdfImageControl ImageControl = new PdfImageControl();
                            ImageControl.Resolution = 96.0;
                            ImageControl.ImageQuality = 50;

                            PdfImage newImage = new PdfImage(Document, fileX);
                            width = rapp * width;
                            height = rapp * height;
                            //                     newImage.ImageSizeAndDensity(width, height, 150.0);
                            if (bAngle)
                            {
                                Contents.Translate(PntX, PntY);
                                Contents.TranslateScaleRotate(0.0, 0.0, 1.0, angleR);
                                Contents.DrawImage(newImage, 0.0, 0.0, width, height);
                                Contents.TranslateScaleRotate(0.0, 0.0, 1.0, -angleR);
                                Contents.Translate(-PntX, -PntY);
                            }
                            else
                            {
                                Contents.DrawImage(newImage, PntX, PntY, width, height);
                            }
                            continue;
                        }
                    }

                    if (codice == 1)
                    {
                        double diam = 0.8;
                        Contents.DrawOval(PntX, PntY, diam, diam, PaintOp.CloseStroke);
                    }


                }
                Contents.RestoreGraphicsState();
            
            //
            //      area_shp
            //
            Contents.SaveGraphicsState();
            Contents.DrawRectangle(Orig_X, Orig_Y, DispWidth, DispHeight, PaintOp.ClipPathWnr);

            for (int i = 0; i < ViewQ.nShapesA; ++i) //  ViewQ.nShapesA; ++i)
            {
                int nVertices = ViewQ.vectShapesA[i].nVertices;
                int ipnt = ViewQ.vectShapesA[i].pntPA;
                int nParts = ViewQ.vectShapesA[i].nParts;
                int[] ipart = new int[nParts + 1];
                if (nParts == 1)
                {
                    ipart[0] = 0;
                    ipart[1] = nVertices;
                }
                else
                {
                    string sp = ViewQ.vectShapesA[i].Parts_string;
                    words = sp.Split(delimiterChars0);
                    for (int j = 0; j < nParts; ++j) ipart[j] = int.Parse(words[j]);
                    ipart[nParts] = nVertices;
                }
                int pntSimb = ViewQ.vectShapesA[i].pntSimb;

                if (ViewQ.vectA[pntSimb].selected == 0) continue;
                int visib = ViewQ.vectA[pntSimb].visib;
                if (visib == 0) continue;

                string codice = ViewQ.vectA[pntSimb].codice;
                bool bEdif = false;
                if (codice.Contains("4A000ED")) bEdif = true;
                if (codice.Contains("4A000TE")) bEdif = true;
                if (codice.Contains("4A000IN")) bEdif = true;
                if (codice.Contains("4A000CU")) bEdif = true;
                if (codice.Contains("4A000AF")) bEdif = true;
                if (codice.Contains("4A000SM")) bEdif = true;
                if (codice.Contains("4A000BA")) bEdif = true;

                Color icolor = ViewQ.vectA[pntSimb].icolor;
                Contents.SetColorStroking(icolor);

                int type = ViewQ.vectA[pntSimb].codice_bordo;
                string ss = ViewQ.vectA[pntSimb].bordo;

                string s1;
                int ipos;
                int len;
                double[] dashValues = { 0, 0 };
                double dist_linee = 0;
                double offset = 0;
                double width = 0.0;
                switch (type)
                {
                    case 1:
                        ipos = ss.IndexOf('/');
                        ++ipos;
                        len = ss.Length;
                        s1 = ss.Substring(ipos, len - ipos);
                        width = double.Parse(s1, nfi);
                        break;
                    case 5:
                        ipos = ss.IndexOf('/');
                        ++ipos;
                        len = ss.Length;
                        s1 = ss.Substring(ipos, len - ipos);
                        words = s1.Split(delimiterChars0);
                        width = double.Parse(words[2], nfi);
                        dashValues[0] = double.Parse(words[0], nfi);
                        dashValues[1] = double.Parse(words[1], nfi);
                        break;
                    default:
                        width = 0;
                        break;
                }

                if (width == 0.0) continue;
                Contents.SetLineWidth(width);
                if (dashValues[0] > 0) Contents.SetDashLine(dashValues, 0);
                else Contents.SetDashLine(null, 0);

                PointF[] polyD = new PointF[1];

                for (int k = 0; k < nParts; ++k)
                {
                    ipnt = ViewQ.vectShapesA[i].pntPA + ipart[k];
                    int iVertices = ipart[k + 1] - ipart[k];
                    polyD = new PointF[iVertices];
                    for (int j = 0; j < iVertices; ++j)
                    {

                        double XX1 = 1000.0 * (ViewQ.PA[ipnt].X - ViewQ.Xmin) * scala;
                        double YY1 = 1000.0 * (ViewQ.PA[ipnt].Y - ViewQ.Ymin) * scala - YYtrasl;
                        polyD[j].X = (float)(XX1 * cosA + YY1 * sinA) + (float)Xoff;
                        polyD[j].Y = (float)(-XX1 * sinA + YY1 * cosA) + (float)Yoff;
                        ++ipnt;
                    }
                    if (bEdif) drawLines(Contents, polyD);
                    else drawLines(Contents, polyD);
                }

                type = ViewQ.vectA[pntSimb].codice_camp;
                if (type == 0) continue;
                ss = ViewQ.vectA[pntSimb].campitura;
                switch (type)
                {
                    case 1:
                        ipos = ss.IndexOf('/');
                        ++ipos;
                        len = ss.Length;
                        s1 = ss.Substring(ipos, len - ipos);
                        words = s1.Split(delimiterChars0);
                        width = double.Parse(words[2], nfi);
                        dashValues[0] = double.Parse(words[0], nfi);
                        dashValues[1] = double.Parse(words[1], nfi);
                        dist_linee = double.Parse(words[3], nfi);
                        offset = double.Parse(words[4], nfi);
                        int mst = 1;
                        arenile1(Contents, nVertices, dashValues[0], dashValues[1], dist_linee, offset, i, mst);
                        break;

                    case 2:
                        ipos = ss.IndexOf('/');
                        ++ipos;
                        len = ss.Length;
                        s1 = ss.Substring(ipos, len - ipos);
                        words = s1.Split(delimiterChars0);
                        dashValues[0] = double.Parse(words[0], nfi);
                        dashValues[1] = double.Parse(words[1], nfi);
                        width = double.Parse(words[2], nfi);
                        offset = double.Parse(words[3], nfi);       //  inclinazione
                        dist_linee = double.Parse(words[4], nfi);
                        int lst = 1;
                        roccia(Contents, nVertices, dashValues[0], dashValues[1], dist_linee, offset, i, lst);
                        break;

                    default:
                        width = 0;
                        break;
                }
            }
            Contents.RestoreGraphicsState();

        }

            void drawLines(PdfContents Contents, PointF[] PolyD)


        {
            int len = PolyD.Length;

            Contents.MoveTo(PolyD[0].X, PolyD[0].Y);

            for (int i = 1; i < len; ++i) Contents.LineTo(PolyD[i].X, PolyD[i].Y);

            Contents.SetPaintOp(PaintOp.Stroke);

        }

        public struct areaInt
        {
            public int nPoints;
            public int ipnt;
            public float Xmin;
            public float Xmax;
            public float Ymin;
            public float Ymax;
        }



        public void roccia(PdfFileWriter.PdfContents Contents, int nVertices, double dash0, double dash1, double dist_linee, double inclinazione, int ist, int lst)
        {
//
//
//            
            char[] delimiterChars0 = { ',', '/' };
            string[] words;
            
            int nParts = ViewQ.vectShapesA[ist].nParts;

            int[] ipart = new int[nParts + 1];
            if (nParts > 1)
            {
                string sp = ViewQ.vectShapesA[ist].Parts_string;
                words = sp.Split(delimiterChars0);
                for (int j = 0; j < nParts; ++j) ipart[j] = int.Parse(words[j]);
            }
            else ipart[0] = 0;
            ipart[nParts] = nVertices;

            double alphaIn = 0;
            calcolo_inclinazione(ist, ref alphaIn);

            alphaIn = Math.PI * alphaIn / 180.0; 
            
            int[] lpart = new int[nParts + 1];
            areaInt[] vect = new areaInt[nParts+1];

            int nPoints = 0;
            PointF[] polyD = new PointF[1];
            PointF[] poly1 = new PointF[1];
            PointF[] poly = new PointF[1];

            double scala = 1.0 / double.Parse(this.textBox1.Text);
            double Xdiff = 1000 * (ViewQ.Xmax - ViewQ.Xmin) * scala;
            double Ydiff = 1000 * (ViewQ.Ymax - ViewQ.Ymin) * scala;

            double YYtrasl = 1000.0 * (ViewQ.vert[0].Y - ViewQ.vert[3].Y) * scala;

            double alphaR = ViewQ.alpha* Math.PI / 180.0D;
            double sinA = Math.Sin(alphaR);
            double cosA = Math.Cos(alphaR);
            double Ydiff1 = Ydiff - YYtrasl;

            double RGyy1 = height1 * Ydiff1 / DispHeight;
            double initXX = initX;
            double initYY = RGyy1 - initY - height1;
            double XX = initXX * cosA - initYY * sinA;
            double YY = initXX * sinA + initYY * cosA;
            double Xoff = Orig_X - (initXX / RGxx) * Xdiff;
            double Yoff = Orig_Y - (initYY / RGyy1) * Ydiff1;

            double valueX = 5.0;
            double valueY = 5.0;
 
            float xMin = 0;
            float xMax = 0;
            float yMin = 0;
            float yMax = 0;
//
//      per ogni area interna definire i puntatori, i vettori con coordinate locali e rettangoli d'ingombro
//
//      rotazione dell'area
//
            float sinAIn = (float)Math.Sin(alphaIn);
            float cosAIn = (float)Math.Cos(alphaIn);

//      fissare dei valori per lo schermo e la stampa
                float interp = 2;
                if (lst == 1) interp = 0.5F; 
//      nel loop seguente si considera il bordo esterno
            for (int k = 0; k < 1; ++k)
            {
                int ipnt = ViewQ.vectShapesA[ist].pntPA + ipart[k];
                int iVertices = ipart[k + 1] - ipart[k];
                polyD = new PointF[iVertices];
                for (int j = 0; j < iVertices; ++j)
                {
                    double XX1 = 1000.0 * (ViewQ.PA[ipnt].X - ViewQ.Xmin) * scala;
                    double YY1 = 1000.0 * (ViewQ.PA[ipnt].Y - ViewQ.Ymin) * scala - YYtrasl;
                    polyD[j].X = (float)(XX1 * cosA + YY1 * sinA) + (float)Xoff;
                    polyD[j].Y = (float)(-XX1 * sinA + YY1 * cosA) + (float)Yoff;
                    ++ipnt;
                }

                for (int j = 0; j < iVertices; ++j)
                {
                    double XX1 = polyD[j].X;
                    double YY1 = polyD[j].Y;
                    polyD[j].X = (float)(XX1 * cosAIn + YY1 * sinAIn);
                    polyD[j].Y = (float)(-XX1 * sinAIn + YY1 * cosAIn);
                }

                normalize(polyD, ref poly1, interp, ist);

                nPoints = poly1.Length;
                poly = new PointF[nPoints];

                ipnt = ipart[k];
                vect[k].ipnt = ipnt;
                vect[k].nPoints = nPoints;

                for (int i = 0; i < nPoints; ++i) poly[i+ipnt] = poly1[i];

                xMin = poly[ipnt].X;
                xMax = poly[ipnt].X; 
                yMin = poly[ipnt].Y;
                yMax = poly[ipnt].Y;

                for (int i = 1; i < nPoints; ++i)
                {
                    int ii = i + ipnt;
                    if (poly[ii].X < xMin) xMin = poly[ii].X;
                    if (poly[ii].X > xMax) xMax = poly[ii].X;
                    if (poly[ii].Y < yMin) yMin = poly[ii].Y;
                    if (poly[ii].Y > yMax) yMax = poly[ii].Y;
                }
                vect[k].Xmin = xMin;
                vect[k].Xmax = xMax;
                vect[k].Ymin = yMin;
                vect[k].Ymax = yMax;
            }


            PointF[] poly11 = new PointF[1];
            PointF[] polyZ = new PointF[nVertices];

            int nPoints1 = 0;

            if (nParts == 1) goto L100;

            int mpnt = 0;

//      nel loop seguente si considerano i bordi interni
            for (int k = 1; k < nParts; ++k)
            {
                int ipnt = ViewQ.vectShapesA[ist].pntPA + ipart[k];
                int iVertices = ipart[k + 1] - ipart[k];
                polyD = new PointF[iVertices];
                for (int j = 0; j < iVertices; ++j)
                {
                    double XX1 = 1000.0 * (ViewQ.PA[ipnt].X - ViewQ.Xmin) * scala;
                    double YY1 = 1000.0 * (ViewQ.PA[ipnt].Y - ViewQ.Ymin) * scala - YYtrasl;
                    polyD[j].X = (float)(XX1 * cosA + YY1 * sinA) + (float)Xoff;
                    polyD[j].Y = (float)(-XX1 * sinA + YY1 * cosA) + (float)Yoff;
                    ++ipnt;
                }

                for (int j = 0; j < iVertices; ++j)
                {
                    double XX1 = polyD[j].X;
                    double YY1 = polyD[j].Y;
                    polyD[j].X = (float)(XX1 * cosAIn + YY1 * sinAIn);
                    polyD[j].Y = (float)(-XX1 * sinAIn + YY1 * cosAIn);
                }

                normalize(polyD, ref poly1, interp, ist);

                nPoints = poly1.Length;
 
                vect[k].ipnt = mpnt;
                vect[k].nPoints = nPoints;

                for (int i = 0; i < nPoints; ++i) polyZ[i + mpnt] = poly1[i];

                xMin = polyZ[mpnt].X;
                xMax = polyZ[mpnt].X;
                yMin = polyZ[mpnt].Y;
                yMax = polyZ[mpnt].Y;

                for (int i = 1; i < nPoints; ++i)
                {
                    int ii = i + mpnt;
                    if (polyZ[ii].X < xMin) xMin = polyZ[ii].X;
                    if (polyZ[ii].X > xMax) xMax = polyZ[ii].X;
                    if (polyZ[ii].Y < yMin) yMin = polyZ[ii].Y;
                    if (polyZ[ii].Y > yMax) yMax = polyZ[ii].Y;
                }
                vect[k].Xmin = xMin;
                vect[k].Xmax = xMax;
                vect[k].Ymin = yMin;
                vect[k].Ymax = yMax;

                mpnt += nPoints;
            }
            vect[nParts].ipnt = mpnt; 
     
  L100:
            float x1 = 0;
            float x2 = 0;
            float y2 = 0;
            float Xpos0 = 0;
            float[] Xpos = new float[20];
            float[] XXpos = new float[20];
            int[] ipos = new int[20];
            int irept = 0;
            int jj = 0;
            float yPos = vect[0].Ymin;

            int inumMax = 10 * nParts;
            float[] Xpos1 = new float[inumMax];
            float[] XXpos1 = new float[inumMax];
            int[] ipos1 = new int[inumMax];

       L10: yPos += (float)dist_linee;
            if (yPos >= vect[0].Ymax) return;
//
//      irept = numero di intersezioni della retta orizzontale yPos con il bordo esterno
//
            irept = 0;
            nPoints = vect[0].nPoints;

            for (int ii = 0; ii < nPoints - 1; ++ii)
            {
                if (poly[ii].Y > poly[ii + 1].Y)
                    if (yPos >= poly[ii + 1].Y && yPos < poly[ii].Y) ++irept;
                if (poly[ii].Y < poly[ii + 1].Y)
                    if (yPos < poly[ii + 1].Y && yPos >= poly[ii].Y) ++irept;
            }
            int irept2 = irept / 2;
            if (2 * irept2 < irept) goto L10;   //  le intersezioni dovrebbero essere di numero pari
            if (irept > 18) goto L10;
            ++jj;

            int inum = 0;

  // calcolo intersezioni retta orizzontale con bordo esterno 
                inum = 0;
                for (int ii = 0; ii < nPoints - 1; ++ii)
                {
 //                   if (poly[ii].Y < 4.0) continue;
                    if (poly[ii].Y > poly[ii + 1].Y)
                    {
                        if (yPos >= poly[ii + 1].Y && yPos < poly[ii].Y)
                        {
                            x1 = poly[ii].X;
                            x2 = poly[ii + 1].X;
                            y2 = poly[ii + 1].Y;
                            Xpos0 = (yPos - y2) * (x1 - x2) / (poly[ii].Y - y2) + x2;
                            Xpos[inum] = Xpos0;
                            ++inum;
                        }
                        continue;
                    }
                    if (poly[ii].Y < poly[ii + 1].Y)
                        if (yPos < poly[ii + 1].Y && yPos >= poly[ii].Y)
                        {
                            x1 = poly[ii].X;
                            x2 = poly[ii + 1].X;
                            y2 = poly[ii + 1].Y;
                            Xpos0 = (yPos - y2) * (x1 - x2) / (poly[ii].Y - y2) + x2;
                            Xpos[inum] = Xpos0;
                            ++inum;
                        }
                    if (inum >= 18) break;
                }
//
//      riordino vettore Xpos secondo valori crescenti
//
                for (int i = 0; i < inum; ++i) ipos[i] = 0;
                for (int j = 0; j < inum; ++j)
                {
                    int k = 0;
                    for (k = 0; k < inum; ++k)
                    {
                        if (ipos[k] == 0)
                        {
                            xMin = Xpos[k];
                            break;
                        }
                    }

                    int iptx = 0;
                    for (int i = 0; i < inum; ++i)
                    {
                        float fXP = Xpos[i];
                        if (i != k)
                        {
                            if (xMin > Xpos[i] && ipos[i] == 0)
                            {
                                xMin = Xpos[i];
                                iptx = i;
                            }
                        }
                        if (i == k) iptx = i;
                    }
                    XXpos[j] = Xpos[iptx];
                    ipos[iptx] = 1;
                }

                int imax = (inum + 1) / 2;
                float x5 = 0;
                float x6 = 0;
                float dashT = (float)(dash0 + dash1);

                for (int i = 0; i < imax; ++i)
                {
                    int j = 2 * i;
                    x5 = XXpos[j];
                    xMax = XXpos[j + 1];
                    if (x5 > xMax) continue;

//
//          calcolo intersezioni con curva interna
//
                    if (nParts == 1) goto L30;

                    inum = 0;
                    for (int ik = 1; ik < nParts; ++ik)
                    {
                        if (vect[ik].Ymin > yPos) continue;
                        if (vect[ik].Ymax < yPos) continue;
                        if (x5 > vect[ik].Xmax) continue;
                        if (xMax < vect[ik].Xmin) continue;
                        nPoints1 = vect[ik + 1].ipnt - vect[ik].ipnt;

                        mpnt = vect[ik].ipnt;
                        poly11 = new PointF[nPoints1];
                        for (int ii = 0; ii < nPoints1; ++ii) poly11[ii] = polyZ[ii + mpnt];

                        irept = 0;
                        for (int ii = 0; ii < nPoints1 - 1; ++ii)
                        {
                            if (poly11[ii].Y > poly11[ii + 1].Y)
                                if (yPos >= poly11[ii + 1].Y && yPos < poly11[ii].Y) ++irept;
                            if (poly11[ii].Y < poly11[ii + 1].Y)
                                if (yPos < poly11[ii + 1].Y && yPos >= poly11[ii].Y) ++irept;
                        }

                        if (irept == 0) continue;

                        float xx1 = 0;
                        float xx2 = 0;
                        float yy2 = 0;

                        for (int ii = 0; ii < nPoints1 - 1; ++ii)
                        {
                            if (poly11[ii].Y > poly11[ii + 1].Y)
                            {
                                if (yPos >= poly11[ii + 1].Y && yPos < poly11[ii].Y)
                                {
                                    xx1 = poly11[ii].X;
                                    xx2 = poly11[ii + 1].X;
                                    yy2 = poly11[ii + 1].Y;
                                    Xpos0 = (yPos - yy2) * (xx1 - xx2) / (poly11[ii].Y - yy2) + xx2;
                                    Xpos1[inum] = Xpos0;
                                    ++inum;
                                }
                                continue;
                            }
                            if (poly11[ii].Y < poly11[ii + 1].Y)
                                if (yPos < poly11[ii + 1].Y && yPos >= poly11[ii].Y)
                                {
                                    xx1 = poly11[ii].X;
                                    xx2 = poly11[ii + 1].X;
                                    yy2 = poly11[ii + 1].Y;
                                    Xpos0 = (yPos - yy2) * (xx1 - xx2) / (poly11[ii].Y - yy2) + xx2;
                                    Xpos1[inum] = Xpos0;
                                    ++inum;
                                }
                            if (inum >= inumMax) break;
                        }
                    }


//
//      riordino vettore Xpos1 secondo valori crescenti
//

                    if (inum == 0) goto L30;
                    for (int ik = 0; ik < inum; ++ik) ipos1[ik] = 0;
                    for (int jk = 0; jk < inum; ++jk)
                    {
                        int k = 0;
                        for (k = 0; k < inum; ++k)
                        {
                            if (ipos1[k] == 0)
                            {
                                xMin = Xpos1[k];
                                break;
                            }
                        }
                        int iptx = 0;
                        for (int ik = 0; ik < inum; ++ik)
                        {
                            float fXP = Xpos1[ik];
                            if (ik != k)
                            {
                                if (xMin > Xpos1[ik] && ipos1[ik] == 0)
                                {
                                    xMin = Xpos1[ik];
                                    iptx = ik;
                                }
                            }
                            if (ik == k) iptx = ik;
                        }
                        XXpos1[jk] = Xpos1[iptx];
                        ipos1[iptx] = 1;
                    }

                    double X1 = 0;
                    double Y1 = 0;
                    double X2 = 0;
                    double Y2 = 0;
                    int inum2 = inum / 2;
                    int ip = 0;
                    for (int ik = 0; ik < inum2; ++ik)
                    {
                        float xMax1;
                        xMax1 = XXpos1[ip];
                    L20: x6 = x5 + (float)dash0;
                        if (x6 > xMax1) x6 = xMax1;
                        X1 = x5 * cosAIn - yPos * sinAIn;
                        Y1 = x5 * sinAIn + yPos * cosAIn;
                        X2 = x6 * cosAIn - yPos * sinAIn;
                        Y2 = x6 * sinAIn + yPos * cosAIn;
                        if (X1 > valueX && Y1 > valueY) Contents.DrawLine(X1, Y1, X2, Y2);

                        x5 = x6 + (float)dash1;
                        if (x5 < xMax1) goto L20;

                        x5 = XXpos1[ip + 1];
                        ip += 2;
                    }

                L25: x6 = x5 + (float)dash0;
                    if (x6 > xMax) x6 = xMax;
                    X1 = x5 * cosAIn - yPos * sinAIn;
                    Y1 = x5 * sinAIn + yPos * cosAIn;
                    X2 = x6 * cosAIn - yPos * sinAIn;
                    Y2 = x6 * sinAIn + yPos * cosAIn;
                    if (X1 > valueX && Y1 > valueY) Contents.DrawLine(X1, Y1, X2, Y2);
                    x5 = x6 + (float)dash1;
                    if (x5 < xMax) goto L25;

                    continue;

                L30: x6 = x5 + (float)dash0;
                    if (x6 > xMax) x6 = xMax;
                    X1 = x5 * cosAIn - yPos * sinAIn;
                    Y1 = x5 * sinAIn + yPos * cosAIn;
                    X2 = x6 * cosAIn - yPos * sinAIn;
                    Y2 = x6 * sinAIn + yPos * cosAIn;
                    if (X1 > valueX && Y1 > valueY) Contents.DrawLine(X1, Y1, X2, Y2);
                    x5 = x6 + (float)dash1;
                    if (x5 < xMax) goto L30;
                }
                goto L10;
        }


        private void calcolo_inclinazione(int ist, ref double alphaR)
        {
            //
            //
            //
            char[] delimiterChars0 = { ',', '/' };
            string[] words;
            NumberFormatInfo nfi = new CultureInfo("en-US", false).NumberFormat;

            int nParts = ViewQ.vectShapesA[ist].nParts;
            int nVertices = ViewQ.vectShapesA[ist].nVertices;

            int[] ipart = new int[nParts + 1];
            if (nParts > 1)
            {
                string sp = ViewQ.vectShapesA[ist].Parts_string;
                words = sp.Split(delimiterChars0);
                for (int j = 0; j < nParts; ++j) ipart[j] = int.Parse(words[j]);
            }
            else ipart[0] = 0;
            ipart[nParts] = nVertices;
            //
            //        selezione punti o vertici del contorno esterno dell'area
            //

            int ipnt = ViewQ.vectShapesA[ist].pntPA + ipart[0];
            int nPoints = ipart[1] - ipart[0];
            if (nPoints < 10) return;

            int inc = 1;
            int iPoints = 0;

        L5: iPoints = nPoints - 100 * inc;
            if (iPoints > 0)
            {
                ++inc;
                goto L5;
            }
            nPoints = nPoints / inc;

            Point[] polygon = new Point[nPoints];

            for (int i = 0; i < nPoints; ++i)
            {
                polygon[i].X = ViewQ.PA[ipnt].X;
                polygon[i].Y = ViewQ.PA[ipnt].Y;
                ipnt += inc;
            }

            int[] elev = new int[nPoints];
            Point Hit = new Point(0, 0);
            int isel_max = 300;
            int[] ipt = new int[isel_max];
            int[] elev1 = new int[isel_max];
            //
            //          calcolo quota dei vertici del contorno esterno dell'area
            //                    
            for (int i = 0; i < nPoints; ++i)
            {
                Hit.X = polygon[i].X;
                Hit.Y = polygon[i].Y;
                //
                //          prima selezione curve di livello vicine al vertice i
                //          la ricerca viene effettuata con il criterio delle aree incluse nei rettangoli di definizione
                //          delle curve di livello
                //
                int isel = 0;
                for (int j = 0; j < ViewQ.nShapes; ++j)
                {
                    int pntSimb = ViewQ.vectShapes[j].pntSimb;
                    if (ViewQ.vectS[pntSimb].codice.Contains("1L000CD")) goto L11;
                    if (ViewQ.vectS[pntSimb].codice.Contains("1L000CI")) goto L11;
                    if (ViewQ.vectS[pntSimb].codice.Contains("1L000DI")) goto L11;
                    if (ViewQ.vectS[pntSimb].codice.Contains("1L000II")) goto L11;
                    continue;
                L11:
                    if (Hit.X < ViewQ.vectShapes[j].PointA.X) continue;
                    if (Hit.X > ViewQ.vectShapes[j].PointB.X) continue;
                    if (ViewQ.vectShapes[j].PointA.Y < ViewQ.vectShapes[j].PointB.Y)
                    {
                        if (Hit.Y < ViewQ.vectShapes[j].PointA.Y) continue;
                        if (Hit.Y > ViewQ.vectShapes[j].PointB.Y) continue;
                    }
                    else
                    {
                        if (Hit.Y > ViewQ.vectShapes[j].PointA.Y) continue;
                        if (Hit.Y < ViewQ.vectShapes[j].PointB.Y) continue;

                    }
                    ipt[isel] = j;
                    ++isel;
                    if (isel == isel_max)
                    {
                        MessageBox.Show("superato limite vettore ipt :" + isel_max.ToString() + " per area " + ist.ToString());
                        break;
                    }
                }

                if (isel == isel_max) return;

                //
                //          seconda selezione curve di livello vicine al vertice i
                //
                int idiff = 30;

                int X1 = Hit.X - idiff;
                int Y1 = Hit.Y - idiff;
                int X2 = Hit.X + idiff;
                int Y2 = Hit.Y + idiff;

                int nsel = 0;

                for (int j = 0; j < isel; ++j)
                {
                    int jj = ipt[j];
                    int iVertices = ViewQ.vectShapes[jj].nVertices;
                    int lpnt = ViewQ.vectShapes[jj].pntpL;

                    int kk = 0;
                    for (kk = 0; kk < iVertices; ++kk)
                    {
                        int i1 = 0;
                        if (ViewQ.PL[lpnt].X > X1 && (ViewQ.PL[lpnt].X < X2)) ++i1;
                        if (ViewQ.PL[lpnt].Y > Y1 && (ViewQ.PL[lpnt].Y < Y2)) ++i1;
                        if (i1 == 2) break;
                        ++lpnt;
                    }
                    if (kk < iVertices) ++nsel;
                    else ipt[j] = -jj;
                }

                if (nsel == 0)
                {
                    //              MessageBox.Show("non trovata nessuna linea che comprenda il punto selezionato - 3 " + ist.ToString() +  " " + isel.ToString());
                    //      è possibile che le curve di ivello abiano origine nelle aree di roccia ad es. area 14 elemento 33131
                    return;
                }
                //
                //              ricerca della curva più vicina al vertice i
                //
                int[] hMin = new int[isel];
                for (int j = 0; j < isel; ++j)
                {
                    int jj = ipt[j];
                    elev1[j] = 0;
                    hMin[j] = -1;
                    if (jj < 0) continue;
                    elev1[j] = (int)float.Parse(ViewQ.vectShapes[jj].quota, nfi);
                    if (elev1[j] == 0) continue;
                    int iVertices = ViewQ.vectShapes[jj].nVertices;
                    int lpnt = ViewQ.vectShapes[jj].pntpL;
                    int[] vect1 = new int[iVertices];
                    //
                    //              calcolo distanza di ogni curva dal vertice i
                    //
                    for (int m = 0; m < iVertices; ++m)
                    {
                        int xdiff = ViewQ.PL[lpnt].X - Hit.X;
                        int ydiff = ViewQ.PL[lpnt].Y - Hit.Y;
                        vect1[m] = xdiff * xdiff + ydiff * ydiff;
                        ++lpnt;
                    }

                    int ixMin = vect1[0];
                    int mm = 0;
                    for (int m = 1; m < iVertices; ++m)
                    {
                        if (ixMin > vect1[m])
                        {
                            ixMin = vect1[m];
                            mm = m;
                        }
                    }
                    hMin[j] = ixMin;
                }
                int j1 = 0;
                for (j1 = 0; j1 < isel; ++j1) if (ipt[j1] > 0) break;
                if (j1 == isel)
                {
                    MessageBox.Show("area " + ist.ToString() + " anomala " + i.ToString() + " " + nsel.ToString() + " " + nPoints.ToString() + " " + nVertices.ToString());
                    return;
                }
                int xMin1 = hMin[j1];
                int jj1 = j1;
                for (int j = j1; j < isel; ++j)
                {
                    if (ipt[j] < 0) continue;
                    if (xMin1 > hMin[j])
                    {
                        xMin1 = hMin[j];
                        jj1 = j;
                    }
                }

                elev[i] = elev1[jj1];
            }
            //
            //          quota minima e massima del contorno
            //
            int hMin1 = elev[0];
            int mm1 = 0;
            int hMax = elev[0];
            int mm2 = 0;
            for (int i = 0; i < nPoints; ++i)
            {
                if (hMin1 > elev[i])
                {
                    hMin1 = elev[i];
                    mm1 = i;
                }
                if (hMax < elev[i])
                {
                    hMax = elev[i];
                    mm2 = i;
                }
            }

            int ix1 = polygon[mm1].X;
            int iy1 = polygon[mm1].Y;
            int ix2 = polygon[mm2].X;
            int iy2 = polygon[mm2].Y;
            int idx = ix2 - ix1;
            int idy = iy2 - iy1;
            int dxx = idx;
            if (idx < 0) dxx = -idx;
            if (dxx < 5)
            {
                alphaR = Math.PI / 2;
            }
            else
            {
                alphaR = Math.Atan2((double)idy, (double)idx);
            }

        }
        private void regress(Point[] poly2, ref float AA, int ist)
        {

            int inum = poly2.Length;

            float x1 = 0;
            float y1 = 0;
            for (int i = 0; i < inum; ++i)
            {
                x1 += poly2[i].X;
                y1 += poly2[i].Y;
            }

            float x2 = 0;

            for (int i = 0; i < inum; ++i)
            {
                x2 += poly2[i].X * poly2[i].X;
            }

            float x1y1 = 0;
            for (int i = 0; i < inum; ++i)
            {
                x1y1 += poly2[i].X * poly2[i].Y;
            }

            AA = (inum * x1y1 - x1 * y1) / (inum * x2 - x1 * x1);
        }


    }
}
